﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

namespace FishServe.Build.Module
{
    public static class AssemblyResolver
    {
        static string _applicationDir;
        static string _modulesFolderName;

        static Dictionary<string, Assembly> _assemblies;

        public static void Initialise(string applicationDir, string modulesFolderName)
        {
            _applicationDir = applicationDir;
            _modulesFolderName = modulesFolderName;

            _assemblies = new Dictionary<string, Assembly>();
            AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }

        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly assembly = null;
            if (!_assemblies.TryGetValue(args.Name, out assembly))
            {
                // TODO: resolve ObjectBuilder2 properly
                string assemblyFullFilename = "";
                AssemblyName assemblyName = new AssemblyName(args.Name);

                if (assemblyName.Name == "Microsoft.Practices.ObjectBuilder2")
                {
                    string unityModuleName = "Microsoft.Practices.Unity";
                    string unityModuleVersion = "1.2.0.0";
                    assemblyFullFilename = Path.Combine(Path.Combine(Path.Combine(Path.Combine(_applicationDir, _modulesFolderName), unityModuleName), unityModuleVersion), assemblyName.Name + ".dll");
                }
                else
                    assemblyFullFilename = Path.Combine(Path.Combine(Path.Combine(Path.Combine(_applicationDir, _modulesFolderName), assemblyName.Name), assemblyName.Version.ToString()), assemblyName.Name + ".dll");

                if (File.Exists(assemblyFullFilename))
                    assembly = Assembly.LoadFrom(assemblyFullFilename);
            }

            return assembly;
        }

        static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
        {
            // TODO: Check args.LoadedAssembly.Location/Codebase to confirm that the assembly is being loaded from the correct location
            Assembly assembly = args.LoadedAssembly;
            _assemblies[assembly.FullName] = assembly;
        }
    }
}
